# -*- coding: utf-8 -*-
## zixue@taobao.com
## 2008-6-16

import string
import time
import  urllib
import md5
from xml.dom import minidom

from TbDomain import *
from HttpClient import HttpClient
from Log import *


class ApiError(Exception):
	def __init__(self, msg):
		self.msg = msg

class ApiResult():
	def __init__(self):
		self.rsp = None
		self.code = None
		self.msg = None
		self.url = None
	
	def isSuccess(self):
		return self.code is None

class TbApi():
	## date format
	ISOTIMEFORMAT= '%Y-%m-%d %X'

	def __now__(self):
		stime = None
		if(time.timezone == 0):
			gmtimefix = 28800
			stime = time.gmtime(gmtimefix + time.time())
		else:
			stime = time.localtime()
		strtime = time.strftime( TbApi.ISOTIMEFORMAT, stime)
		#Log.debug("time:" + strtime)
		return strtime

	def __errfxml__(self, root, rs):
		if(root.nodeName == 'error_rsp'):
			nodes = root.childNodes
			for node in nodes:
				value = node.firstChild.toxml()
				if (node.nodeName == 'code'):
					rs.code = string.atoi(value)
				elif (node.nodeName == 'msg'):
					rs.msg = value
				## TODO compatible sip error msg 
				elif (node.nodeName == 'url'):
					rs.url = value

	def __xmltxt__(self, xml):
		 return xml.toxml() if xml else None

	def __usersfxml__(self, root, rs):
		users = []
		if(root.nodeName == 'rsp'):
			for userEle in root.childNodes:
				if (userEle.nodeName == 'user'):
					user = TbUser()
					for prop in userEle.childNodes:
						if(prop.nodeName == 'nick'):
							user.nick = self.__xmltxt__(prop.firstChild)
						elif(prop.nodeName == 'phone'):
							user.phone = self.__xmltxt__(prop.firstChild)
						elif(prop.nodeName == 'seller_credit'):
							credit = TbCredit()
							for p in prop.childNodes:
								if(p.nodeName == 'level'):
									credit.level = self.__xmltxt__(p.firstChild)
							user.seller_credit = credit
						elif(prop.nodeName == 'buyer_credit'):
							credit = TbCredit()
							for p in prop.childNodes:
								if(p.nodeName == 'level'):
									credit.level = self.__xmltxt__(p.firstChild)
							user.buyer_credit = credit
					users.append(user)
		rs.rsp = users

	def __tradesfxml__(self, root, rs):
		trades = []
		if(root.nodeName == 'rsp'):
			for tradeEle in root.childNodes:
				if (tradeEle.nodeName == 'trade'):
					trade = TbTrade()
					for prop in tradeEle.childNodes:
						value =  prop.firstChild if prop.firstChild else None
						value = value.wholeText if value.wholeText else value.toxml()
						if(prop.nodeName == 'tid'):
							trade.tid = value
						elif(prop.nodeName == 'title'):
							trade.title = value
						elif(prop.nodeName == 'price'):
							trade.price = value
						elif(prop.nodeName == 'seller_nick'):
							trade.seller_nick = value
						elif(prop.nodeName == 'buyer_nick'):
							trade.buyer_nick = value
						elif(prop.nodeName == 'num'):
							trade.num = value
						elif(prop.nodeName == 'status'):
							trade.status = value
						elif(prop.nodeName == 'created'):
							trade.created = value
					trades.append(trade)
		rs.rsp = trades

	def __itemsfxml__(self, root, rs):
		items = []
		if(root.nodeName == 'rsp'):
			for itemEle in root.childNodes:
				if (itemEle.nodeName == 'item'):
					item = TbItem()
					for prop in itemEle.childNodes:
						value =  prop.firstChild if prop.firstChild else None
						value = value.wholeText if getattr(value, 'wholeText', None) else value.toxml()
						if(prop.nodeName == 'iid'):
							item.iid = value
						elif(prop.nodeName == 'title'):
							item.title = value
						elif(prop.nodeName == 'price'):
							item.price = value
						elif(prop.nodeName == 'num'):
							item.num = value
						elif(prop.nodeName == 'nick'):
							item.nick = value
						elif(prop.nodeName == 'pic_path'):
							item.pic_path = value
						elif(prop.nodeName == 'seller_cids'):
							item.seller_cids = value
					items.append(item)
		rs.rsp = items

	def __init__(self, apiConfig):
		self.httpClient = None
		self.apiConfig = apiConfig

	def __sign__(self, params):
		encrypt = md5.new()
		encrypt.update(self.apiConfig.secret)
		for k, v in sorted(params.items()):
			encrypt.update(k)
			encrypt.update(v)
		return encrypt.hexdigest().upper()
		#signSrc = self.apiConfig.secret + ''.join(["%s%s" % (k, v) for k, v in sorted(params.items())])
		#return md5.new(signSrc).hexdigest().upper()

	def __reqAndRsp__(self, req):
		## sign request
		req['sip_sign'] = self.__sign__(req)
		url = self.apiConfig.url + "?" + urllib.urlencode(req)
		rsp = self.httpClient.get(url)
		xmldoc = minidom.parseString(rsp.content)
		#Log.debug("rsp xml:\n" + xmldoc.toxml()) 
		return xmldoc.firstChild

	def __getReq__(self, apiname):
		req = {'sip_appkey':self.apiConfig.appkey, 'v':self.apiConfig.v}
		req['sip_apiname'] = apiname
		req['sip_timestamp'] = self.__now__()
		return req

	def getUser(self, fields, nick):
		if((fields is None) | (nick is None)):
			raise ApiError
		req = self.__getReq__('taobao.user.get')
		req['nick'] = nick
		req['fields'] = fields
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__usersfxml__(root, rs)
		return rs

	def getUsers(self, fields, nicks):
		if((nicks is None) | (fields is None)):
			raise ApiError
		req = self.__getReq__('taobao.users.get')
		req['nicks'] = nicks
		req['fields'] = fields
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__usersfxml__(root, rs)
		return rs

	def getBoughtTrades(self, fields,  session, pageNo=1,  pageSize=40,  title=None, status=None, startCreated=None, endCreated=None):
		if((fields is None) | (session is None)):
			raise ApiError
		req = self.__getReq__('taobao.trades.bought.get')
		req['fields'] = fields
		req['sip_sessionid'] = session
		req['page_size'] = str(pageSize)
		req['page_no'] = str(pageNo)
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__tradesfxml__(root, rs)
		return rs

	def getSoldTrades(self, fields,  session, pageNo=1,  pageSize=40,  title=None, status=None, startCreated=None, endCreated=None):
		if((fields is None) | (session is None)):
			raise ApiError
		req = self.__getReq__('taobao.trades.sold.get')
		req['fields'] = fields
		req['sip_sessionid'] = session
		req['page_size'] = str(pageSize)
		req['page_no'] = str(pageNo)
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__tradesfxml__(root, rs)
		return rs

	def getInstockItems(self, fields, session, pageNo=1,  pageSize=40):
		if((fields is None) | (session is None)):
			raise ApiError
		req = self.__getReq__('taobao.items.instock.get')
		req['fields'] = fields
		req['sip_sessionid'] = session
		req['page_size'] = str(pageSize)
		req['page_no'] = str(pageNo)
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__itemsfxml__(root, rs)
		return rs

	def getOnsaleItems(self, fields, session, pageNo=1,  pageSize=40):
		if((fields is None) | (session is None)):
			raise ApiError
		req = self.__getReq__('taobao.items.onsale.get')
		req['fields'] = fields
		req['sip_sessionid'] = session
		req['page_size'] = str(pageSize)
		req['page_no'] = str(pageNo)
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__itemsfxml__(root, rs)
		return rs

	def getItems(self, pageSize, pageNo, fields, q=None, cid=None, nicks=None):
		if((fields is None)):
			raise ApiError
		req = self.__getReq__('taobao.items.get')
		req['fields'] = fields
		if(pageSize is not None): req['page_size'] = pageSize
		if(pageNo is not None): req['page_no'] = pageNo
		if(q is not None): req['q'] = q
		if(q is not None): req['q'] = q
		if(cid is not None): req['cid'] = cid
		if(nicks is not None): req['nicks'] = nicks
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__itemsfxml__(root, rs)
		return rs

	def getItem(self, fields, iid, nick):
		if(fields is None | iid is None | nick is None):
			raise ApiError
		req = self.__getReq__('taobao.item.get')
		req['fields'] = fields
		if(pageSize is not None): req['page_size'] = pageSize
		if(pageNo is not None): req['page_no'] = pageNo
		if(q is not None): req['q'] = q
		if(q is not None): req['q'] = q
		if(cid is not None): req['cid'] = cid
		if(nicks is not None): req['nicks'] = nicks
		root = self.__reqAndRsp__(req)
		rs = ApiResult()
		self.__errfxml__(root, rs)
		if(rs.isSuccess()):
			self.__itemsfxml__(root, rs)
		return rs

def main():
		Log.enableDebug = True
		Log.adapter =  PrintLog()

		## replace with your app secret and app key
		class ApiConfig():
			appkey = '1'
			secret = '32b'
			url="http://192.168.206.169:8080/top/services/rest"
			#url = 'http://sip.alisoft.com/sip/rest/'
			v = '1.0'
		config = ApiConfig()
		api = TbApi(config)
		api.httpClient = HttpClient()

		## call user.get
		nick = 'alipublic20'
		fields = 'nick,buyer_credit.level,seller_credit'
		rs =  api.getUser(fields, nick)
		if(rs.isSuccess()):
			print 'nicks:' + ','.join(["%s" %  k.nick for k in rs.rsp])
		else :
			print rs.code
			print rs.msg
		## call users.get
		nicks = 'zizaitest10006,alipublic21'
		rs = api.getUsers(fields, nicks)
		if(rs.isSuccess()):
			for k in rs.rsp:
				print 'nick:' + k.nick
				print 'seller_credit.level:' + k.seller_credit.level
		else :
			print rs.code
			print rs.msg
		## call items.get
		fields = 'iid,title,price,cid,nick,pic_path'
		#q = '2008'.decode('gbk').encode('utf-8')
		q='2008'
		rs = api.getItems(50, 1, fields, q)
		if(rs.isSuccess()):
			for k in rs.rsp:
				print 'title:' + k.title + '| nick:' + k.nick + '| pic_path:' + str(k.pic_path)
		else :
			print rs.code
			print rs.msg		
		## call trades.bought.get
		fields = 'title,price,seller_nick'
		rs = api.getBoughtTrades(fields, '2332')
		if(rs.isSuccess()):
			print 'titles:' + ','.join(["%s" %  k.title for k in rs.rsp])
		else :
			print rs.code
			print rs.msg
			if(rs.code == 1004):
				print rs.url

if __name__ == "__main__":
	main()